#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@Author   : long.hai
@Contact  : 1982964634@qq.com
"""
import json
import asyncio
import platform
import traceback
from contextlib import asynccontextmanager

import aio_pika
from _base.base import BasePage
from _controller.runner import BaseRunner
from _step.base import BaseStep
from _step.step import TestCaseList
from playwright.async_api import async_playwright
from control.load_variable import LoadVariable
from utils.common import now


async def task_run(data: dict):
    async with async_playwright() as playwright:
        try:
            # 初始化对象
            base_page = BasePage(playwright)
            lv = LoadVariable(base_page)
            base_step = BaseStep(base_page)

            report_id = data["report_id"]
            base_page.report_id = report_id
            # 连接浏览器/启动新的浏览器
            system_name = platform.system()
            if system_name == "Windows":
                await base_page.conn_debug_chrome()  # firefox chromium
            # elif system_name == "Linux":
            #     await my_playwright.init_linux("chromium")

            # 加载全局变量和环境变量
            await lv.global_and_env(data["variable"])
            # 执行项目初始化
            base_runner = BaseRunner(base_page, lv, base_step)
            init_cases = TestCaseList(data["init"])
            await base_runner.batch_run(init_cases)
            project_init_status = base_runner.report_status
            # 执行测试用例
            if project_init_status == 1:
                # 执行用例
                test_cases = TestCaseList(data["case"])
                await base_runner.batch_run(test_cases)
            else:
                base_runner.completed += len(data["case"])
            if project_init_status == 1:
                # 执行项目后置用例
                reset_cases = TestCaseList(data["reset"])
                await base_runner.batch_run(reset_cases)
            else:
                base_runner.completed += len(data["reset"])
        except Exception as e:
            traceback.print_exc()
        finally:
            update_json = {"report_id": report_id, "data": {"status": base_runner.report_status, "end_time": now()}}
            await base_step.update_test_report(update_json)


async def on_message(message: aio_pika.IncomingMessage, channel, queue):
    msg_body = json.loads(message.body)
    print("接收到消息")
    msg = {"report_id": msg_body["report_id"], "data": {"status": 4, "start_time": now()}}
    print(msg)
    # await send_msg(json.dumps(msg))
    report_message = json.dumps(msg)
    await channel.default_exchange.publish(aio_pika.Message(body=report_message.encode()), routing_key=queue.name)
    # update_json = {"report_id": msg_body["report_id"], "data": {"status": 4, "start_time": now()}}
    # await BaseStep.update_test_report(update_json)
    # await task_run(msg_body)


async def receive():
    try:
        connection = await aio_pika.connect_robust('amqp://admin:longhai123@124.220.103.163:5672/')
        channel = await connection.channel()
        queue = await channel.declare_queue("ui_test")
        queue2 = await channel.declare_queue("ui_report")
        # await queue.consume(on_message)
        async with queue.iterator() as queue_iter:
            async for message in queue_iter:
                await on_message(message, channel, queue2)
                await message.ack()
    except Exception as e:
        print(e)


# 全局变量来存储连接和通道
_connection = None
_channel = None
_queue = None


# 异步上下文管理器来管理连接和通道的创建和关闭
async def producer() -> aio_pika.Channel:
    global _connection, _channel, _queue

    if not _connection or not _connection.is_open:
        _connection = await aio_pika.connect_robust('amqp://admin:longhai123@124.220.103.163:5672/')
        _channel = await _connection.channel()
        print("_channel", _channel)
        _queue = await _channel.declare_queue("ui_report")


# 发送消息到队列的函数
async def send_msg(message: str):
    global _channel, _queue
    await _channel.default_exchange.publish(aio_pika.Message(body=message.encode()), routing_key=_queue.name)
    print(f"Sent message '{message}' to queue '{_queue.name}'")


def start_consumer():
    asyncio.set_event_loop(asyncio.new_event_loop())
    asyncio.get_event_loop().run_until_complete(receive())
    asyncio.get_event_loop().run_forever()


def start_producer():
    asyncio.set_event_loop(asyncio.new_event_loop())
    asyncio.get_event_loop().run_until_complete(producer())
    asyncio.get_event_loop().run_forever()
